<template>
  <Modal v-model="modalVisible" :title="isEdit ? '编辑告警服务' : '新增告警服务'" :mask-closable="false" @on-cancel="modalManiCancel" width="1000px">
    <div class="modal-alert-box">
      <Form ref="modalForm" :model="modalForm" :rules="modalRules" :label-width="70" label-position="left">
        <FormItem label="任务名称" prop="jobName">
          <Row :gutter="10">
            <Col span="8">
              <Input v-model="modalForm.jobName" placeholder="请输入任务名称" :disabled="isEdit" ></Input>
            </Col>
          </Row>
        </FormItem>
        <FormItem label="收信人" :required="true">
          <Row :gutter="10" v-for="receiver in receiverList" :key="receiver.id" class="fold-list-item">
            <Col :span="8">
              <Input v-model="receiver.email" placeholder="admin@chalco-steering.com"></Input>
            </Col>
            <Col :span="3">
              <Icon type="ios-remove-circle-outline" v-if="receiverList.length > 1" class="remove-icon" @click="minusItem(receiver)" />
            </Col>
          </Row>
          <Button type="primary" @click="addItem"><Icon type="md-add"></Icon> 添加收信人</Button>
        </FormItem>
        <FormItem label="描述" prop="messageDescription">
          <Row :gutter="10">
            <Col span="8">
              <Input v-model="modalForm.messageDescription" placeholder="请输入描述"></Input>
            </Col>
          </Row>
        </FormItem>
        <FormItem label="告警规则">
          <Row :gutter="10" v-for="rule in ruleList" :key="rule.id" class="alert-rule-item">
            <Col span="6">
              <Select v-model="rule.ruleMetaDesc" :filterable="true" placeholder="模块" @on-change="selectModule(rule)">
                <Option :value="ruleMeta.describe" :key="ruleMeta.describe" v-for="ruleMeta in ruleInfo">{{ruleMeta.describe}}</Option>
              </Select>
            </Col>
            <Col span="2" v-if="rule.isExtra">
              <Select v-model="rule.alarmLevel">
                <Option :value="level.value" :key="level.value" v-for="level in ALERT_LEVEL">{{level.label}}</Option>
              </Select>
            </Col>
            <Col span="2" v-if="rule.queryFrequence">
              <Select v-model="rule.queryFrequence" placeholder="查询频率">
                <Option :value="frequency.value" :key="frequency.value" v-for="frequency in FREQUENCYS">{{frequency.label}}</Option>
              </Select>
            </Col>
            <Col span="3" v-if="rule.isExtra">
              <Select v-model="rule.aggMethod" placeholder="聚合方式">
                <Option :value="aggregation.value" :key="aggregation.value" v-for="aggregation in AGGREGATIONES">{{aggregation.label}}</Option>
              </Select>
            </Col>
            <Col span="3" v-if="rule.isExtra">
              <Select v-model="rule.ruleEnum" placeholder="告警规则" @on-change="selectAlarmRule(rule)">
                <Option :value="alarm.value" :key="alarm.value" v-for="alarm in ALARM_RULE">{{alarm.label}}</Option>
              </Select>
            </Col>
            <Col span="2" v-if="!rule.isBetween && rule.isExtra">
              <Input v-model="rule.thresholds[0]" placeholder="阈值"></Input>
            </Col>
            <Col span="6" v-if="rule.isBetween">
              <Row :gutter="6">
                <Col span="12">
                  <Input v-model="rule.thresholds[0]" @on-blur="validateBetween($event, 'min', rule)">
                    <div slot="prepend">最小值</div>
                  </Input>
                </Col>
                <Col span="12">
                  <Input v-model="rule.thresholds[1]" @on-blur="validateBetween($event, 'max', rule)">
                    <div slot="prepend">最大值</div>
                  </Input>
                </Col>
              </Row>
            </Col>
            <Col span="1" v-if="rule.isExtra">{{rule.unit}}</Col>
            <Col span="1">
              <Icon type="ios-remove-circle-outline" class="remove-icon" @click="minusRuleItem(rule)" />
            </Col>
            <Col span="24" v-if="rule.optionsObj" class="alert-option" v-for="(value, key) in rule.optionsObj" :key="key">
              <h4 class="option-title">{{key}} (参数以,分割)</h4>
              <Input v-model="rule.optionsObj[key]" type="textarea" :rows="3" @on-blur="$limitLen($event, 4096)"></Input>
            </Col>
          </Row>
          <Button type="primary" @click="addRuleItem"><Icon type="md-add"></Icon> 添加告警规则</Button>
        </FormItem>
      </Form>
    </div>
    <div slot="footer">
      <Button type="warning" @click="modalManiCancel">取消</Button>
      <Button type="primary" :loading="isLoading" @click="modalManiConf">确定</Button>
    </div>
  </Modal>
</template>
<script type="text/javascript">
import uuid from 'uuid/v4'
import Fetch from '@/api/request'
export default {
  data() {
    const validateName = (rule, value, callback) => {
      let regName = /^(?![0-9-])[a-zA-Z0-9\-\u4e00-\u9fa5]*$/
      if (!value) {
        callback(new Error('请输入名称'))
      } else if (!regName.test(value)) {
        callback(new Error('由英文字母、数字、-、中文组成，不能以数字或-开头'))
      } else if (value.length < 4) {
        callback(new Error('最小长度不能少于4位'))
      } else if (value.length > 128) {
        callback(new Error('最大长度不能大于128位'))
      } else {
        callback()
      }
    }
    const validateLength = (rule, value, callback) => {
      if (value && value.length > 250) {
        callback(new Error('最大长度不能大于250位'))
      } else {
        callback()
      }
    }
    return {
      modalForm: {
        jobName: '',
        messagePushType: 'EMAIL',
        receivers: [],
        messageDescription: ''
      },
      isLoading: false,
      modalRules: {
        jobName: [{required: true, trigger: 'blur', validator: validateName}],
        messageDescription: [{required: false, trigger: 'blur', validator: validateLength}]
      },
      modalVisible: false,
      receiverList: [{
        id: uuid(),
        email: ''
      }],
      ALERT_LEVEL: [{
        label: '危险',
        value: 'danger'
      }, {
        label: '警告',
        value: 'warning'
      }, {
        label: '普通',
        value: 'ordinary'
      }],
      FREQUENCYS: [{
        label: '1分钟',
        value: '1m'
      }, {
        label: '5分钟',
        value: '5m'
      }, {
        label: '15分钟',
        value: '15m'
      }, {
        label: '30分钟',
        value: '30m'
      }, {
        label: '1小时',
        value: '1h'
      }, {
        label: '6小时',
        value: '6h'
      }, {
        label: '12小时',
        value: '12h'
      }],
      AGGREGATIONES: [{
        label: '平均值',
        value: 'AVG'
      }, {
        label: '最小值',
        value: 'MIN'
      }, {
        label: '最大值',
        value: 'MAX'
      }, {
        label: '求和',
        value: 'SUM'
      }, {
        label: '总数',
        value: 'COUNT'
      }, {
        label: '变化量',
        value: 'STATS'
      }, {
        label: '平均速率',
        value: 'AVGSPEED'
      }],
      ALARM_RULE: [{
        label: '大于',
        value: 'GT'
      }, {
        label: '大于等于',
        value: 'GTE'
      }, {
        label: '小于',
        value: 'LT'
      }, {
        label: '小于等于',
        value: 'LTE'
      }, {
        label: '等于',
        value: 'EQ'
      }, {
        label: '区间',
        value: 'BETWEEN'
      }, {
        label: '空值',
        value: 'NULL'
      }],
      ruleList: [],
      ruleInfo: [],
      isEdit: false
    }
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    form: {
      type: Object,
      default: function () {
        return {}
      }
    }
  },
  methods: {
    // 校验区间值
    validateBetween(event, type, rule) {
      // 最小值
      if (type === 'min') {
        if (event.currentTarget.value === '') {
          return
        } else if (isNaN(parseFloat(event.currentTarget.value))) {
          event.currentTarget.value = ''
          this.$Message.warning({
            content: '最小值需为整数或小数',
            duration: 3
          })
        } else if (!isNaN(parseFloat(rule.thresholds[1])) && parseFloat(rule.thresholds[1]) < parseFloat(event.currentTarget.value)) {
          // 最小值大于最大值
          this.$Message.warning({
            content: '最小值不能大于最大值',
            duration: this.DURATION
          })
          event.currentTarget.value = ''
        } else {
          event.currentTarget.value = parseFloat(event.currentTarget.value)
        }
      }
      if (type === 'max') {
        if (event.currentTarget.value === '') { // 不判断就会执行下一步从而提示
        } else if (isNaN(parseFloat(event.currentTarget.value))) {
          event.currentTarget.value = ''
          this.$Message.warning({
            content: '最大值需为整数或小数',
            duration: 3
          })
        } else if (!isNaN(parseFloat(rule.thresholds[0])) && parseFloat(rule.thresholds[0]) > parseFloat(event.currentTarget.value)) {
          // 最小值大于最大值
          this.$Message.warning({
            content: '最大值不能小于最小值',
            duration: this.DURATION
          })
          event.currentTarget.value = ''
        } else {
          event.currentTarget.value = parseFloat(event.currentTarget.value)
        }
      }
    },
    // 选择告警规则
    selectAlarmRule(rule) {
      rule.isBetween = rule.ruleEnum === 'BETWEEN'
    },
    // 选择规则模块，用于获取模块默认参数
    selectModule(rule) {
      for (let i = 0; i < this.ruleInfo.length; i++) {
        const ruleMeta = this.ruleInfo[i]
        if (ruleMeta.describe === rule.ruleMetaDesc) {
          rule = Object.assign(rule, {
            metricId: ruleMeta.ruleMetaId,
            queryFrequence: ruleMeta.suggestQueryFrequence,
            aggMethod: ruleMeta.suggestAggMethod,
            ruleEnum: ruleMeta.suggestRuleEnum,
            alarmLevel: ruleMeta.alarmLevel,
            ruleMetaDesc: ruleMeta.describe,
            unit: ruleMeta.unit
          })
          if (ruleMeta.options) {
            // 返回options数据value可能是字符串，也可能是数组，必须全部转化为字符串用于展示
            let t = JSON.parse(ruleMeta.options)
            let temp = {}
            for (const key in t) {
              if (t.hasOwnProperty(key)) {
                const e = t[key]
                if (typeof e === 'string') {
                  temp[key] = e
                } else if (Array.isArray(e)) {
                  temp[key] = JSON.stringify(e)
                }
              }
            }
            rule.optionsObj = temp
          } else {
            rule.optionsObj = null
          }
          rule.isExtra = ruleMeta.alertObject !== 'exist'
        }
      }
    },
    // 获取规则列表，用于告警
    getRuleInfo() {
      Fetch.get({
        url: '/api/scheduler-job/alert/metaInfo'
      }).then((res) => {
        if (res && res.code === '0') {
          this.ruleInfo = res.data
        } else {
          this.$Message.warning({
            content: res.message,
            duration: this.DURATION
          })
        }
      }).catch((err) => {
        this.$Message.error(err.message)
      })
    },
    // 确定操作
    modalManiConf() {
      this.$refs['modalForm'].validate((valid) => {
        if (valid) {
          this.isLoading = true
          // 收信人处理
          if (this.receiverList.length === 0) {
            this.$Message.warning({
              content: '请至少填写一个收信人！',
              duration: this.DURATION
            })
            return
          }
          this.modalForm.receivers = []
          for (let i = 0; i < this.receiverList.length; i++) {
            const receiver = this.receiverList[i]
            receiver.email && this.modalForm.receivers.push(receiver.email)
          }
          // 告警规则处理
          let t = []
          for (let i = 0; i < this.ruleList.length; i++) {
            const rule = this.ruleList[i]
            // 区间值，两个值为区间
            let thresholds = [rule.thresholds[0]]
            if (rule.thresholds[0] && rule.thresholds[1]) {
              thresholds = rule.thresholds
            }
            if (thresholds[0] === '') {
              thresholds = null
            }

            t.push({
              metricId: rule.metricId,
              queryFrequence: rule.queryFrequence,
              aggMethod: rule.aggMethod,
              ruleEnum: rule.ruleEnum,
              alarmLevel: rule.alarmLevel,
              ruleMetaDesc: rule.ruleMetaDesc,
              unit: rule.unit,
              thresholds: thresholds,
              options: rule.optionsObj ? rule.optionsObj : {}
            })
          }

          let params = Object.assign({}, this.modalForm, {alertJobInfoVOS: t})
          let reqPromise
          if (this.isEdit) {
            reqPromise = Fetch.put({
              url: '/api/scheduler-job/alert/update/' + this.modalForm.jobName,
              params
            })
          } else {
            reqPromise = Fetch.post({
              url: '/api/scheduler-job/alert',
              params
            })
          }
          reqPromise.then((res) => {
            if (res && res.code === '0') {
              this.$Message.success({
                content: this.isEdit ? '编辑告警服务(' + this.modalForm.jobName + ')成功！' : '添加告警服务（' + this.modalForm.jobName + '）成功！',
                duration: this.DURATION
              })
            } else {
              this.$Message.warning({
                content: res.message,
                duration: this.DURATION
              })
            }
            this.$emit('finish')
            this.$emit('update:visible', false)
            this.isLoading = false
          }).catch((err) => {
            this.isLoading = false
            this.$Message.error(err.message)
          })
        }
      })
    },
    // 取消操作
    modalManiCancel() {
      this.$emit('update:visible', false)
    },
    // 减少收信人
    minusItem(receiver) {
      // 至少有一个收信人
      if (this.receiverList.length === 1) {
        return
      }
      this.receiverList = this.receiverList.filter((item) => {
        return item.id !== receiver.id
      })
    },
    // 添加收信人
    addItem() {
      // 用于限制无限制添加
      if (this.receiverList.length > 50) {
        this.$Message.info({
          content: '路径列表数量不能超过50个',
          duration: this.DURATION
        })
        return
      }
      this.receiverList.push({
        id: uuid(),
        email: ''
      })
    },
     // 减少告警规则
    minusRuleItem(receiver) {
      this.ruleList = this.ruleList.filter((item) => {
        return item.id !== receiver.id
      })
    },
    // 添加告警规则
    addRuleItem() {
      // 用于限制无限制添加
      if (this.ruleList.length > 20) {
        this.$Message.info({
          content: '路径列表数量不能超过20个',
          duration: this.DURATION
        })
        return
      }
      this.ruleList.push({
        id: uuid(),
        isBetween: false,
        isExtra: false, // 用于判断展示额外参数
        thresholds: ['', '']
      })
    }
  },
  watch: {
    visible(val) {
      this.modalVisible = val
      if (val) {
        this.getRuleInfo()
        // 编辑参数初始化
        if (this.form.jobName) {
          this.isEdit = true
          this.modalForm = {
            jobName: this.form.jobName,
            messagePushType: 'EMAIL',
            receivers: [],
            messageDescription: this.form.messageDescription
          }
          // 收信人列表
          let rl = []
          if (this.form.receivers) {
            for (let i = 0; i < this.form.receivers.length; i++) {
              rl.push({
                id: uuid(),
                email: this.form.receivers[i]
              })
            }
          }
          this.receiverList = rl
          // 告警规则
          // this.ruleList = this.form.alertJobInfoVOS
          let temp = []
          for (let i = 0; i < this.form.alertJobInfoVOS.length; i++) {
            const alertJob = this.form.alertJobInfoVOS[i]
            let isExtra = false
            if (alertJob.aggMethod || alertJob.ruleEnum || alertJob.thresholds) {
              isExtra = true
            }
            let thresholds = ['', '']
            if (alertJob.thresholds) {
              if (alertJob.thresholds.length === 1) {
                thresholds[0] = alertJob.thresholds[0]
              } else if (alertJob.thresholds.length === 2) {
                thresholds = alertJob.thresholds
              }
            }
            // 可选值参数如果是数组，需处理成字符串才能在Input里面进行展示
            let optionsObj = null
            if (alertJob.options) {
              optionsObj = {}
              for (const key in alertJob.options) {
                if (alertJob.options.hasOwnProperty(key)) {
                  const option = alertJob.options[key]
                  if (typeof option === 'string') {
                    optionsObj[key] = option
                  } else if (Array.isArray(option)) {
                    optionsObj[key] = JSON.stringify(option)
                  }
                }
              }
            }

            temp.push({
              id: uuid(),
              isBetween: alertJob.ruleEnum === 'BETWEEN',
              isExtra: isExtra, // 用于判断展示额外参数
              thresholds,
              metricId: alertJob.metricId,
              queryFrequence: alertJob.queryFrequence,
              aggMethod: alertJob.aggMethod,
              ruleEnum: alertJob.ruleEnum,
              alarmLevel: alertJob.alarmLevel,
              ruleMetaDesc: alertJob.ruleMetaDesc,
              unit: alertJob.unit,
              optionsObj: optionsObj
            })
          }
          this.ruleList = temp
        } else {
          this.isEdit = false
          this.modalForm = {
            jobName: '',
            messagePushType: 'EMAIL',
            receivers: [],
            messageDescription: ''
          }
          this.receiverList = [{
            id: uuid(),
            email: ''
          }]
          this.ruleList = []
        }
        this.$refs.modalForm.resetFields()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.modal-alert-box /deep/ {
  .ivu-select-single .ivu-select-selection .ivu-select-placeholder,
  .ivu-select-single .ivu-select-selection .ivu-select-selected-value {
    padding-right: 17px;
    padding-left: 5px;
  }
  .ivu-select-arrow {
    right: 5px;
  }
}
.alert-rule-item {
  margin-bottom: 10px;
  margin-left: 0!important;
  padding: 10px 5px;
  background-color: #f5f5f5;
  border: 1px solid #eee;
  border-radius: 4px;
}
.alert-option {
  .option-title {
    color: #999;
    font-weight: normal;
  }
}
</style>
